package com.kellycheung.chicken_go_go;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.SurfaceHolder;
import android.view.Window;
import android.view.WindowManager;

import com.kellycheung.chicken_go_go.GMediaPlayer.GMPType;
import com.kellycheung.chicken_go_go.GTouchPoint.TouchAction;

public class GameEngine extends Thread implements SurfaceHolder.Callback {
	public class YesNoDialog extends Thread implements DialogInterface.OnClickListener {
		protected GameEngine geMain;
		protected String sTitle;
		protected String sMsg;
		protected ButtonFunction bfYes;
		protected ButtonFunction bfNo;
		protected AlertDialog.Builder adDialog;
		protected long lDialogDelay;
		
		public YesNoDialog( GameEngine p_ge , String p_sTitle , String p_sMsg , ButtonFunction p_bfYes , ButtonFunction p_bfNo , long p_lDialogDelay ) {
			try {
				this.geMain = p_ge;
				this.sTitle = p_sTitle;
				this.sMsg = p_sMsg;
				this.bfYes = p_bfYes;
				this.bfNo = p_bfNo;
				this.adDialog = new AlertDialog.Builder( this.geMain.aApp )
					.setTitle( this.sTitle )
					.setMessage( this.sMsg )
					.setPositiveButton( "Yes" , this )
				    .setNegativeButton( "No" , this );
				this.lDialogDelay = p_lDialogDelay;
	        } catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "YesNoDialog" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		@Override
		public void run() {
			try {
				Timer t = new Timer();
				t.schedule( new TimerTask() {
					@Override
					public void run() {
						// TODO Auto-generated method stub
						geMain.aApp.runOnUiThread( new Runnable() {
							@Override
							public void run() {
								// TODO Auto-generated method stub
					        	try {
					        		adDialog.show();
						        } catch ( Exception p_e ) {
									// TODO Auto-generated catch block
									GameUtil.LogMsg( this , "YesNoDialog.run - Runnable.run" );
									GameUtil.ErrorHandler( this , p_e );
								}
								return;
							}
						});
					}
				}
				,this.lDialogDelay );
	        } catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "YesNoDialog.run" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		@Override
		public void onClick( DialogInterface dialog , int which ) {
			// TODO Auto-generated method stub
        	try {
		        switch (which){
		        case DialogInterface.BUTTON_POSITIVE:
		            //Yes button clicked
					this.bfYes.call();
		            break;
	
		        case DialogInterface.BUTTON_NEGATIVE:
		            //No button clicked
		        	this.bfNo.call();
		            break;
		        }
	        } catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "YesNoDialog.onClick" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
	}
	
	protected Activity aApp;
	protected SurfaceHolder shMain;
	protected GCoordinate gcScreenSize;
	
	protected GameSurfaceView gsvView;
	protected GameScene gsCurrentScene;
	protected GameScene gsNextScene;
	protected GTouchPoint gtpHandler;
	protected GNetworkHandler gnhHandler;
	protected GMediaPlayer gmpPlayer;
	protected GPerferences gpPref;
	
	protected int iDelay;
	protected boolean isGameEnded;
	protected boolean isGamePaused;
	protected int iGameLoopCnt;
	protected String sPackageName;
	protected String sPackageVer;
	protected String sDeviceId;
	
	/*protected int currentHappyLv = 100;
	protected int currentItemQty = 0;
	protected int currentGoldNum = 0;
	protected int currentTokenNum = 0;
	protected int currentItemOneQty = 0;
	protected int currentItemTwoQty = 0;
	protected int currentRaceStage = 1;*/
	
	public GameEngine( Activity p_aApp ) {
		try {
			this.aApp = p_aApp;
			this.iDelay = 1000/30;
			this.isGameEnded = false;
			this.isGamePaused = false;
			this.initGame();
			this.iGameLoopCnt = 0;
			this.gtpHandler = new GTouchPoint( this );
			this.gnhHandler = new GNetworkHandler( this );
	        this.gpPref = new GPerferences( this );
			this.gmpPlayer = new GMediaPlayer( this );
			this.sPackageName = p_aApp.getApplicationContext().getPackageName();
			this.sPackageVer = p_aApp.getPackageManager().getPackageInfo( this.sPackageName , 0 ).versionName;
			this.sDeviceId = Build.SERIAL;
			this.getMenuPerference();
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void destroy() {
		try {
			if ( this.gsvView != null ) {
				this.gsvView.destroy();
				this.gsvView = null;
			}
			
			if ( this.gsCurrentScene != null ) {
				this.gsCurrentScene.destroy();
				this.gsCurrentScene = null;
			}
			
			if ( this.gsNextScene != null ) {
				this.gsNextScene.destroy();
				this.gsNextScene = null;
			}
			
			if ( this.gtpHandler != null ) {
				this.gtpHandler.destroy();
				this.gtpHandler = null;
			}
			
			if ( this.gnhHandler != null ) {
				this.gnhHandler.destroy();
				this.gnhHandler = null;
			}
			
			if ( this.gmpPlayer != null ) {
				this.gmpPlayer.destroy();
				this.gmpPlayer = null;
			}
			
			if ( this.gpPref != null ) {
				this.gpPref.destroy();
				this.gpPref = null;
			}
			
			this.gcScreenSize = null;
			this.shMain = null;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.destroy" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public boolean initGame() {
		try {
			// Initial environment
			this.aApp.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
			this.aApp.requestWindowFeature(Window.FEATURE_NO_TITLE);
			this.aApp.getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN , WindowManager.LayoutParams.FLAG_FULLSCREEN );
			
			DisplayMetrics dm = new DisplayMetrics();
			this.aApp.getWindow().getWindowManager().getDefaultDisplay().getMetrics( dm );
			this.gcScreenSize = new GCoordinate( (float)(dm.widthPixels) , (float)(dm.heightPixels) );
			
			this.gsvView = new GameSurfaceView( this.aApp , this );
			this.shMain = this.gsvView.getHolder();
			this.shMain.addCallback( this );
			this.aApp.setContentView( this.gsvView );
			
			return true;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.initGame" );
			GameUtil.ErrorHandler( this , p_e );
		}
		
		return false;
	}
	
	public Context getAppActivity() {
		return this.aApp;
	}
	
	// Game Scene
	public void addToNextScene( GameScene p_gs ) {
		this.gsNextScene = p_gs;
	}
	
	// Game Scene
	public void changeGameScene() {
		try {
			if ( this.gsNextScene != null ) {
				if ( this.gsCurrentScene != null ) {
					if ( this.gsCurrentScene.iResBGMusic != this.gsNextScene.iResBGMusic ) {
						this.gmpPlayer.stopMusic( GMPType.bgMusic , this.gsCurrentScene.iResBGMusic );
					}
					this.gsCurrentScene.destroy();
					this.gsCurrentScene = null;
				}
				
				this.gsCurrentScene = this.gsNextScene;
				if ( this.gsCurrentScene.iResBGMusic != 0 ) {
					this.gmpPlayer.playMusic( GMPType.bgMusic , this.gsCurrentScene.iResBGMusic );
				}
				this.gsNextScene = null;
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.changeGameScene" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public boolean isGameEnded() {
		return this.isGameEnded;
	}
	
	public void gameStart() {
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			while ( !this.isGameEnded() ) {
				this.iGameLoopCnt++;
				
				// Send Message
				this.networkHandle();
				
				// Input
				this.inputHandle();
				
				// Logic
				if ( this.gsCurrentScene != null ) {
					this.gsCurrentScene.preGameLoopLogic();
					this.gsCurrentScene.gameLoopLogic();
					this.gsCurrentScene.postGameLoopLogic();
				}
				
				// Render
				this.rendering();
			}
			
			this.destroy();
			
			this.aApp.finish();
			
			this.aApp = null;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.run" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	@Override
	public void surfaceDestroyed( SurfaceHolder p_shHolder ) {
	}
		
	@Override
	public void surfaceCreated( SurfaceHolder p_shHolder ) {
		try {
			if ( !this.isAlive() ) {
				this.start();
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.surfaceCreated" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	@Override
	public void surfaceChanged( SurfaceHolder p_shHolder , int p_iFormat , int p_iWidth , int p_iHeight ) {
	}
	
	public void backButtonHandler() {
		try {
			this.gsCurrentScene.backButtonHandler();
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.backButtonHandler" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected void networkHandle() {
		try {
			if ( this.gnhHandler != null ) {
				if ( this.gnhHandler.gnbtHandler != null ) {
					this.gsCurrentScene.pushMsgPre();
					this.gsCurrentScene.readMsgPre();
					this.gsCurrentScene.pushMsgPost();
					this.gsCurrentScene.readMsgPost();
					this.gsCurrentScene.setVarByNetwork();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.networkHandle" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected void inputHandle() {
		try {
			if ( this.gtpHandler != null ) {
				if ( this.gtpHandler.iDelay == 0 ) {
					for (TouchAction ta : this.gtpHandler.getTouchAction() ) {
						this.gsCurrentScene.processInput( ta );
					}
				}
				else {
					this.gtpHandler.iDelay--;
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.inputHandle" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected void rendering()  {
		Canvas c = null;
		
		try {
			c = this.shMain.lockCanvas();
			
			Paint p = new Paint();
			p.setAntiAlias( true );
			p.setFilterBitmap( true );
			p.setDither( true );
			
			if ( c != null ) {
				synchronized ( this.shMain ) {
					this.changeGameScene();
					this.gsCurrentScene.draw( c , p );
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.rendering" );
			GameUtil.ErrorHandler( this , p_e );
		} finally {
			if ( c != null ) {
				this.shMain.unlockCanvasAndPost( c );
			}
		}
	}
	
	public void getMenuPerference() {
		this.gpPref.getPerference( "gpHappyLv" , 100 );
		
		//this.gpPref.getPerference( "gpGoldNum" , 100 );
		this.gpPref.getPerference( "gpGoldNum" , 2 );
		this.gpPref.getPerference( "gpTokenNum" , 0 );
		
		this.gpPref.getPerference( "gpItemNum" , 0 );
		this.gpPref.getPerference( "gpItemOneQty" , 0 );
		this.gpPref.getPerference( "gpItemTwoQty" , 0 );
		this.gpPref.getPerference( "gpItemMax" , 20 );
		
		this.gpPref.getPerference( "gpRaceStage" , 1 );
		this.gpPref.getPerference( "gpMaxStage" , 10 );
		
		/*protected int currentHappyLv = 100;
		protected int currentItemQty = 0;
		protected int currentGoldNum = 0;
		protected int currentTokenNum = 0;
		protected int currentItemOneQty = 0;
		protected int currentItemTwoQty = 0;
		protected int currentRaceStage = 1;*/
		
		/*String happyLv  = this.gpPref.getPerference("gpHappyLv");
	    String itemNum  = this.gpPref.getPerference("gpItemNum");
	    String goldNum  = this.gpPref.getPerference("gpGoldNum");
	    String tokenNum  = this.gpPref.getPerference("gpTokenNum");
	    String raceStage  = this.gpPref.getPerference("gpRaceStage");
	    String itemOneQty  = this.gpPref.getPerference("gpItemOneQty");
	    String itemTwoQty  = this.gpPref.getPerference("gpItemTwoQty");

	    if ( happyLv.equals("") )  {
	    	this.gpPref.setPerference("gpHappyLv" , String.valueOf(this.currentHappyLv));
        }
	    else {
	    	this.currentHappyLv = Integer.parseInt(happyLv);
	    }
	    
	    if ( itemNum.equals("") ) {
	    	this.gpPref.setPerference("gpItemNum" , String.valueOf(this.currentItemQty));
        }
	    else {
	    	this.currentItemQty = Integer.parseInt(itemNum);
	    }
	    
	    if ( goldNum.equals("") ) {
	    	this.gpPref.setPerference("gpGoldNum" , String.valueOf(this.currentGoldNum));
        }
	    else {
        	this.currentGoldNum = Integer.parseInt(goldNum);
	    }
	    
	    if ( tokenNum.equals("") ) {
	    	this.gpPref.setPerference("gpTokenNum" , String.valueOf(this.currentTokenNum));
        }
	    else {
        	this.currentTokenNum = Integer.parseInt(tokenNum);
	    }
	    
	    if ( itemOneQty.equals("") ) {
	    	this.gpPref.setPerference("gpItemOneQty" , String.valueOf(this.currentItemOneQty));
        }
	    else {
        	this.currentItemOneQty = Integer.parseInt(itemOneQty);
	    }
	    
	    if ( itemTwoQty.equals("") ) {
	    	this.gpPref.setPerference("gpItemTwoQty" , String.valueOf(this.currentItemTwoQty));
        }
	    else {
        	this.currentItemTwoQty = Integer.parseInt(itemTwoQty);
	    }
	    
	    if ( raceStage.equals("") ) {
	    	this.gpPref.setPerference("gpRaceStage" , String.valueOf(this.currentRaceStage));
        } 
	    else {
        	this.currentRaceStage = Integer.parseInt(raceStage); 
	    }*/
	}
	
	public void onNewIntent( Intent p_i ) {
		try {
			if ( this.gnhHandler != null ) {
				this.gnhHandler.onNewIntent( p_i );
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.onNewIntent" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void onResume() {
		try {
			if ( this.gnhHandler != null ) {
				this.gnhHandler.onResume();
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.onResume" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void onPause() {
		try {
			if ( this.gnhHandler != null ) {
				this.gnhHandler.onPause();
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.onPause" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void showYesNoDialog( String p_sTitle , String p_sMsg , ButtonFunction p_bfYes , ButtonFunction p_bfNo , long p_lDialogDelay ) {
		try {
			new YesNoDialog( this , p_sTitle , p_sMsg , p_bfYes , p_bfNo , p_lDialogDelay ).run();
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameEngine.showYesNoDialog" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public boolean isAnyBTConnectionCreated() {
		return ( this.gnhHandler != null 
				&& this.gnhHandler.gnbtHandler != null 
				&& this.gnhHandler.gnbtHandler.isAnyConnectionCreated() );
	}
}